package cn.iocoder.yudao.module.project.controller.admin.internalcode;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.project.controller.admin.order.vo.OrderRespVO;
import cn.iocoder.yudao.module.project.controller.admin.orderdetail.vo.OrderDetailPageReqVO;
import cn.iocoder.yudao.module.project.controller.admin.orderdetail.vo.OrderDetailScheduledVO;
import cn.iocoder.yudao.module.project.controller.admin.workstation.vo.WorkstationRespVO;
import cn.iocoder.yudao.module.project.dal.dataobject.electronicscalemanage.ElectronicScaleManageDO;
import cn.iocoder.yudao.module.project.dal.dataobject.productioncode.ProductionCodeDO;
import cn.iocoder.yudao.module.project.dal.dataobject.weighthistory.WeightHistoryDO;
import cn.iocoder.yudao.module.project.dal.dataobject.workstation.WorkstationDO;
import cn.iocoder.yudao.module.project.dal.mysql.electronicscalemanage.ElectronicScaleManageMapper;
import cn.iocoder.yudao.module.project.dal.mysql.internalcode.InternalCodeMapper;
import cn.iocoder.yudao.module.project.dal.mysql.productioncode.ProductionCodeMapper;
import cn.iocoder.yudao.module.project.dal.mysql.weighthistory.WeightHistoryMapper;
import cn.iocoder.yudao.module.project.dal.mysql.workstation.WorkstationMapper;
import cn.iocoder.yudao.module.project.service.electronicscalemanage.ElectronicScaleManageService;
import cn.iocoder.yudao.module.project.service.productprocesscompleted.ProductProcessCompletedService;
import cn.iocoder.yudao.module.system.api.dict.DictDataApi;
import cn.iocoder.yudao.module.system.api.dict.dto.DictDataRespDTO;
import com.alibaba.excel.ExcelWriter;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.springframework.core.io.ClassPathResource;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;

import javax.validation.*;
import javax.servlet.http.*;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.util.*;
import java.io.IOException;
import java.util.stream.Collectors;

import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.error;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;

import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
import static cn.iocoder.yudao.module.project.config.projectDefine.HTTP_STATUS.ERROR_STATUS;
import static cn.iocoder.yudao.module.project.config.projectDefine.HTTP_STATUS.ERROR_STATUS_EXISTS;

import cn.iocoder.yudao.module.project.controller.admin.internalcode.vo.*;
import cn.iocoder.yudao.module.project.dal.dataobject.internalcode.InternalCodeDO;
import cn.iocoder.yudao.module.project.service.internalcode.InternalCodeService;
import org.springframework.web.multipart.MultipartFile;

@Tag(name = "管理后台 - 内码信息")
@RestController
@RequestMapping("/project/internal-code")
@Validated
@Slf4j
public class InternalCodeController {

    @Resource
    private InternalCodeService internalCodeService;

    @Resource
    private InternalCodeMapper internalCodeMapper;

    @Resource
    private ProductionCodeMapper productionCodeMapper;

    @Resource
    private ElectronicScaleManageService electronicScaleManageService;

    @Resource
    private WorkstationMapper workstationMapper;

    @Resource
    private ProductProcessCompletedService productProcessCompletedService;

    @Resource
    private ElectronicScaleManageMapper electronicScaleManageMapper;

    @PostMapping("/create")
    @Operation(summary = "创建内码信息")
    // @PreAuthorize("@ss.hasPermission('project:internal-code:create')")
    public CommonResult<String> createInternalCode(@Valid @RequestBody InternalCodeSaveReqVO createReqVO) {
        return success(internalCodeService.createInternalCode(createReqVO));
    }

    @PutMapping("/update")
    @Operation(summary = "更新内码信息")
    // @PreAuthorize("@ss.hasPermission('project:internal-code:update')")
    public CommonResult<Boolean> updateInternalCode(@Valid @RequestBody InternalCodeSaveReqVO updateReqVO) {
        internalCodeService.updateInternalCode(updateReqVO);
        return success(true);
    }

    @DeleteMapping("/delete")
    @Operation(summary = "删除内码信息")
    @Parameter(name = "id", description = "编号", required = true)
    // @PreAuthorize("@ss.hasPermission('project:internal-code:delete')")
    public CommonResult<Boolean> deleteInternalCode(@RequestParam("id") String id) {
        internalCodeService.deleteInternalCode(id);
        return success(true);
    }

    @GetMapping("/get")
    @Operation(summary = "获得内码信息")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    // @PreAuthorize("@ss.hasPermission('project:internal-code:query')")
    public CommonResult<InternalCodeRespVO> getInternalCode(@RequestParam("id") String id) {
        InternalCodeDO internalCode = internalCodeService.getInternalCode(id);
        return success(BeanUtils.toBean(internalCode, InternalCodeRespVO.class));
    }

    @GetMapping("/page")
    @Operation(summary = "获得内码信息分页")
    // @PreAuthorize("@ss.hasPermission('project:internal-code:query')")
    public CommonResult<PageResult<InternalCodeRespVO>> getInternalCodePage(@Valid InternalCodePageReqVO pageReqVO) {
        PageResult<InternalCodeDO> pageResult = internalCodeService.getInternalCodePage(pageReqVO);
        PageResult<InternalCodeRespVO> result = BeanUtils.toBean(pageResult, InternalCodeRespVO.class);
        if (null != result) {
            List<InternalCodeRespVO> list = result.getList();
            if (CollectionUtil.isNotEmpty(list)) {
                for (InternalCodeRespVO internalCodeRespVO : list) {
                    LocalDateTime createTime = internalCodeRespVO.getCreateTime();
                    LocalDateTime operatingTime = internalCodeRespVO.getOperatingTime();
                    String createTimeStr = DateUtil.format(createTime, "yyyy-MM-dd HH:mm:ss");
                    String operatingTimeStr = DateUtil.format(operatingTime, "yyyy-MM-dd");
                    internalCodeRespVO.setCreateTimeStr(createTimeStr);
                    internalCodeRespVO.setOperatingTimeStr(operatingTimeStr);
                }

                // 设置规格型号,产品长度,订单类型
                this.setFlex(list);
            }
        }
        return success(result);
    }

    // @GetMapping("/export-excel")
    // @Operation(summary = "导出内码信息 Excel")
    // @PreAuthorize("@ss.hasPermission('project:internal-code:export')")
    // @ApiAccessLog(operateType = EXPORT)
    // public void exportInternalCodeExcel(@Valid InternalCodePageReqVO pageReqVO,
    //           HttpServletResponse response) throws IOException {
    //     pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
    //     List<InternalCodeDO> list = internalCodeService.getInternalCodePage(pageReqVO).getList();
    //     // 导出 Excel
    //     ExcelUtils.write(response, "内码信息.xls", "数据", InternalCodeRespVO.class,
    //                     BeanUtils.toBean(list, InternalCodeRespVO.class));
    // }


    @Operation(summary = "导出内码模板 Excel")
    @GetMapping(value = "/exportTemplate")
    public void exportTemplate(HttpServletResponse response) {
        InputStream inputStream = null;
        String fileName = "内码导入模板.xlsx";
        try {
            ClassPathResource classPathResource = new ClassPathResource("/template/内码导入模板.xlsx");
            inputStream = classPathResource.getInputStream();
            Workbook excel = WorkbookFactory.create(inputStream);

            //使用输出流进行表格下载,基于浏览器作为客户端下载
            OutputStream out = response.getOutputStream();
            response.setContentType("application/vnd.ms-excel");//代表的是Excel文件类型
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
            ;//指定以附件形式进行下载
            excel.write(out);
            out.flush();
            out.close();
            excel.close();
        } catch (Exception e) {
        } finally {
            IoUtil.close(inputStream);
        }
    }

    @PostMapping("/importInternalCode")
    @Operation(summary = "导入内码 Excel")
    public CommonResult<Boolean> importInternalCode(@RequestParam("file") MultipartFile file) {
        try {
            long start = System.currentTimeMillis();
            ExcelReader excelReader = ExcelUtil.getReader(file.getInputStream());
            Sheet sheet = excelReader.getSheet();
            List<List<Object>> list = excelReader.read();

            if (CollectionUtil.isNotEmpty(list)) {
                if (list.size() > 2) {
                    List<InternalCodeDO> importDataList = new ArrayList<>();

                    // 从第三行开始读取
                    for (int i = 2; i < list.size(); i++) {
                        InternalCodeDO internalCodeDO = new InternalCodeDO();
                        // 内码编号
                        Object id = list.get(i).get(0);
                        if (id != null && !id.equals("")) {
                            internalCodeDO.setId(id.toString());
                        }

                        // 内码名称
                        Object name = list.get(i).get(1);
                        if (name != null && !name.equals("")) {
                            internalCodeDO.setName(name.toString());
                        }

                        // 物料编号
                        Object materialCode = list.get(i).get(2);
                        if (materialCode != null && !materialCode.equals("")) {
                            internalCodeDO.setMaterialCode(materialCode.toString());
                        }

                        // 批次号
                        Object batchNumber = list.get(i).get(3);
                        if (batchNumber != null && !batchNumber.equals("")) {
                            internalCodeDO.setBatchNumber(batchNumber.toString());
                        }

                        // 批次校验序号
                        Object batchCheckNumber = list.get(i).get(4);
                        if (batchCheckNumber != null && !batchCheckNumber.equals("")) {
                            internalCodeDO.setBatchCheckNumber(batchCheckNumber.toString());
                        }

                        // 备注
                        Object remark = list.get(i).get(5);
                        if (remark != null && !remark.equals("")) {
                            internalCodeDO.setRemark(remark.toString());
                        }

                        // 导入时间
                        LocalDateTime today = LocalDateTimeUtils.getToday();
                        internalCodeDO.setOperatingTime(today);
                        internalCodeDO.setDeleted(false);
                        importDataList.add(internalCodeDO);
                    }

                    internalCodeService.saveRecord(importDataList);
                    System.out.println("取excel完毕：" + (System.currentTimeMillis() - start) + "}毫秒");
                }

            }
        } catch (Exception e) {
            throw new ServiceException(ERROR_STATUS, "导入内码失败");
        }
        return success(true);
    }

    @GetMapping("/exportExcel")
    @Operation(summary = "导出内码信息 Excel")
    @ApiAccessLog(operateType = EXPORT)
    public void exportInternalCodeExcel(@Valid InternalCodePageReqVO pageReqVO,
                                        HttpServletResponse response) throws IOException {

        ExcelWriter excelWriter = null;
        String errorMsg = "导出内码错误：";
        String fileName = "内码" + ".xlsx";
        InputStream inputStream = null;

        try {
            ClassPathResource classPathResource = new ClassPathResource("/template/内码导入模板.xlsx");
            inputStream = classPathResource.getInputStream();
            Workbook excel = WorkbookFactory.create(inputStream);

            pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
            List<InternalCodeDO> list = internalCodeService.getInternalCodePage(pageReqVO).getList();
            List<InternalCodeRespVO> datas = BeanUtils.toBean(list, InternalCodeRespVO.class);

            // 设置规格型号,产品长度,订单类型
            this.setFlex(datas);

            // // 此处查出的数据不分页,暂时注释掉
            // datas = internalCodeService.batchGetInternalCodeList(pageReqVO);

            //读取第一个工作表
            Sheet sheet = excel.getSheetAt(0);

            // rowNumber=1表示从第2行开始
            int rowNumber = 1;

            if (null != datas && datas.size() > 0) {
                Row row = sheet.getRow(rowNumber);

                // 创建一个单元格样式，用于设置边框
                CellStyle style = excel.createCellStyle();
                // 设置边框
                style.setBorderTop(BorderStyle.THIN); // 顶部边框
                style.setBorderBottom(BorderStyle.THIN); // 底部边框
                style.setBorderLeft(BorderStyle.THIN); // 左边边框
                style.setBorderRight(BorderStyle.THIN); // 右边边框
                // 设置水平对齐方式
                style.setAlignment(HorizontalAlignment.CENTER);
                // 设置垂直对齐方式
                style.setVerticalAlignment(VerticalAlignment.CENTER);
                style.setWrapText(true); // 设置单元格内容自动换行

                // 先在第2行插入空白行,行数根据datas的大小来确定
                for (InternalCodeRespVO data : datas) {
                    Row oldRow = sheet.getRow(rowNumber);
                    sheet.shiftRows(rowNumber, sheet.getLastRowNum(), 1);

                    Row newRow = sheet.createRow(rowNumber);
                    if (oldRow != null) {
                        for (int i = 0; i < oldRow.getLastCellNum(); i++) {
                            Cell oldCell = oldRow.getCell(i);
                            Cell newCell = newRow.createCell(i);
                            if (oldCell != null) {
                                newCell.setCellStyle(oldCell.getCellStyle());
                                switch (oldCell.getCellType()) {
                                    case STRING:
                                        newCell.setCellValue(oldCell.getStringCellValue());
                                        break;
                                    case NUMERIC:
                                        newCell.setCellValue(oldCell.getNumericCellValue());
                                        break;
                                    case BOOLEAN:
                                        newCell.setCellValue(oldCell.getBooleanCellValue());
                                        break;
                                    // ... handle other cell types ...
                                }
                            }
                        }
                    }

                    rowNumber++;
                }

                int newRowNumber = 1;
                for (InternalCodeRespVO data : datas) {
                    String id = data.getId();
                    // String name = data.getName();
                    String materialCode = data.getMaterialCode();
                    String batchNumber = data.getBatchNumber();
                    String batchCheckNumber = data.getBatchCheckNumber();
                    String flexType = data.getFlexType();
                    Double len = data.getLen();
                    String orderType = data.getOrderType();

                    row = sheet.getRow(newRowNumber++);

                    if (null != id) {
                        Cell cell = row.createCell(0);
                        cell.setCellValue(id);
                        cell.setCellStyle(style);
                    }
                    if (null != materialCode) {
                        Cell cell = row.createCell(1);
                        cell.setCellValue(materialCode);
                        cell.setCellStyle(style);
                    }
                    if (null != batchNumber) {
                        Cell cell = row.createCell(2);
                        cell.setCellValue(batchNumber);
                        cell.setCellStyle(style);
                    }
                    if (null != batchCheckNumber) {
                        Cell cell = row.createCell(3);
                        cell.setCellValue(batchCheckNumber);
                        cell.setCellStyle(style);
                    }
                    if (null != flexType) {
                        Cell cell = row.createCell(4);
                        cell.setCellValue(flexType);
                        cell.setCellStyle(style);
                    }
                    if (null != len) {
                        Cell cell = row.createCell(5);
                        cell.setCellValue(len);
                        cell.setCellStyle(style);
                    }
                    if (null != orderType) {
                        Cell cell = row.createCell(6);
                        cell.setCellValue(orderType);
                        cell.setCellStyle(style);
                    }
                    if (null != id) {
                        Cell cell = row.createCell(10);
                        cell.setCellValue(id.substring(id.length() - 5));
                        cell.setCellStyle(style);
                    }
                }
            }

            //使用输出流进行表格下载,基于浏览器作为客户端下载
            OutputStream out = response.getOutputStream();
            response.setContentType("application/vnd.ms-excel");//代表的是Excel文件类型
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
            ;//指定以附件形式进行下载
            excel.write(out);
            out.flush();
            out.close();
            excel.close();
        } catch (Exception e) {
            log.error(errorMsg, e);
        } finally {
            IoUtil.close(excelWriter);
        }
    }

    @GetMapping("/exportTxt")
    @Operation(summary = "导出内码数据为txt格式")
    public void exportTxt(@Valid InternalCodePageReqVO pageReqVO, HttpServletResponse response) throws IOException {
        String errorMsg = "导出内码错误：";
        long startTime = System.currentTimeMillis();
        List<InternalCodeRespVO> kisBatchCodeList = internalCodeService.batchGetInternalCodeList(pageReqVO);
        long endTime = System.currentTimeMillis();
        log.info("总耗时:" + (endTime - startTime));

        int capture=4;
        if(kisBatchCodeList.size()>9999){
            capture = 5;
        }

        // 设置规格型号,产品长度,订单类型
        this.setFlex(kisBatchCodeList);

        // 设置响应头
        response.setContentType("text/plain");
        response.setHeader("Content-Disposition", "attachment; filename=internal_codes.txt");

        // 写入数据到响应流
        try (PrintWriter writer = response.getWriter()) {
            // 写入表头
            writer.println("内码编号\t物料编号\t批次号\t批次校验序号\t产品规格\t长度\t订单类型\t日期\t产品流水\t是否打印\t内码简码\t"); // 根据实际字段替换

            // 写入数据
            for (InternalCodeRespVO vo : kisBatchCodeList) {
                writer.println(vo.getId() + "\t"
                        + vo.getMaterialCode() + "\t"
                        + vo.getBatchNumber() + "\t"
                        + vo.getBatchCheckNumber() + "\t"
                        + vo.getFlexType() + "\t"
                        + vo.getLen() + "\t"
                        + vo.getOrderType() + "\t"
                        + "" + "\t"
                        + "" + "\t"
                        + "" + "\t"
                        + vo.getId().substring(vo.getId().length() - capture) + "\t"
                ); // 根据实际字段替换
            }
        } catch (Exception e) {
            log.error(errorMsg, e);
        } finally {
            IoUtil.close(response.getWriter());
        }
    }


    // 此接口影响性能,暂时不用
    @GetMapping("/list")
    @Operation(summary = "获得内码不分页")
    public CommonResult<PageResult<InternalCodeRespVO>> list(@Valid InternalCodePageReqVO pageReqVO) {
        long startTime = System.currentTimeMillis();
        // List<InternalCodeRespVO> kisBatchCodeList = this.getInternalCodeList(pageReqVO);
        List<InternalCodeRespVO> kisBatchCodeList = internalCodeService.batchGetInternalCodeList(pageReqVO);
        long endTime = System.currentTimeMillis();
        log.info("总耗时:" + (endTime - startTime));
        PageResult result = new PageResult();
        result.setList(kisBatchCodeList);
        result.setTotal((long) kisBatchCodeList.size());
        return success(result);
    }

    private List<InternalCodeRespVO> getInternalCodeList(InternalCodePageReqVO pageReqVO) {
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        List<InternalCodeDO> list = internalCodeService.getInternalCodePage(pageReqVO).getList();
        List<InternalCodeRespVO> datas = BeanUtils.toBean(list, InternalCodeRespVO.class);
        // 设置规格型号,产品长度,订单类型
        this.setFlex(datas);
        return datas;
    }

    @PostMapping("/weight")
    @Operation(summary = "上线称重")
    // @PreAuthorize("@ss.hasPermission('project:internal-code:update')")
    public CommonResult<String> updateWeight(@RequestBody InternalCodeSaveReqVO updateReqVO) {

        try {
            // 根据用户id查询绑定的电子秤
            ElectronicScaleManageDO usedScale = electronicScaleManageService.getUsedScale(SecurityFrameworkUtils.getLoginUserId());
            if (null == usedScale) {
                throw new ServiceException(ERROR_STATUS, "用户未绑定电子秤,请绑定电子秤");
            }

            // 判断传过来的是内码还是成品码
            String id = updateReqVO.getId();
            if (StringUtils.isBlank(id)) {
                throw new ServiceException(ERROR_STATUS, "请输入内码");
            }
            ProductionCodeDO productionCodeDO = productionCodeMapper.selectById(id);
            InternalCodeDO internalCodeDO = internalCodeMapper.selectById(id);
            // 如果是成品码,则将内码赋值给id
            if (null != productionCodeDO) {
                String internalCode = productionCodeDO.getInternalCode();
                updateReqVO.setId(internalCode);
            }

            // 二次平衡
            String balanceTwice = updateReqVO.getBalanceTwice();
            if (StringUtils.isBlank(balanceTwice)) {
                // 成品称重操作员
                updateReqVO.setBalanceTwiceWorkstationId(140);
                updateReqVO.setBalanceTwice("");
            }

            String nickname = SecurityFrameworkUtils.getLoginUserNickname();
            updateReqVO.setOperator(nickname);

            String msg = internalCodeService.updateWeight(updateReqVO);

            return success(msg);
        } catch (Exception e) {
            log.error("异常信息，更新出错" + e.getMessage(), e);
            throw new ServiceException(ERROR_STATUS, e.getMessage());
        }
    }

    @PostMapping("/rigidityAndBalance")
    @Operation(summary = "输入刚性和平衡测试结果")
    public CommonResult<Boolean> updateRigidityAndBalance(@RequestBody InternalCodeSaveReqVO updateReqVO) {

        try {
            internalCodeService.rigidityAndBalance(updateReqVO);
        } catch (Exception e) {
            log.error("异常信息，更新出错" + e.getMessage(), e);
            throw new ServiceException(ERROR_STATUS, e.getMessage());
        }
        return success(true);
    }

    @PostMapping("/rigidity")
    @Operation(summary = "输入刚性测试结果")
    // @PreAuthorize("@ss.hasPermission('project:internal-code:update')")
    public CommonResult<Boolean> updateRigidity(@RequestBody InternalCodeSaveReqVO updateReqVO) {

        try {
            String id = updateReqVO.getId();
            if (StringUtils.isBlank(id)) {
                throw new ServiceException(ERROR_STATUS, "请输入内码");
            }
            InternalCodeDO internalCodeDO = internalCodeMapper.selectById(id);
            if (null != internalCodeDO) {
                String rigidity = internalCodeDO.getRigidity();
                if (StringUtils.isNotBlank(rigidity)) {
                    throw new ServiceException(ERROR_STATUS, "该内码" + id + "已经执行了刚性测试");
                }
            }

            LocalDateTime now = LocalDateTime.now();
            updateReqVO.setRigidityTime(now);
            internalCodeService.updateRigidity(updateReqVO);
        } catch (MybatisPlusException mpe) {
            throw new ServiceException(ERROR_STATUS, mpe.getMessage());
        }
        return success(true);
    }

    @PostMapping("/balance")
    @Operation(summary = "输入平衡测试结果")
    // @PreAuthorize("@ss.hasPermission('project:internal-code:update')")
    public CommonResult<Boolean> updateBalance(@RequestBody InternalCodeSaveReqVO updateReqVO) {

        try {
            String id = updateReqVO.getId();
            if (StringUtils.isBlank(id)) {
                throw new ServiceException(ERROR_STATUS, "请输入内码");
            }
            InternalCodeDO internalCodeDO = internalCodeMapper.selectById(id);
            if (null != internalCodeDO) {
                String balance = internalCodeDO.getBalance();
                if (StringUtils.isNotBlank(balance)) {
                    throw new ServiceException(ERROR_STATUS, "该内码" + id + "已经执行了平衡测试");
                }
            }

            LocalDateTime now = LocalDateTime.now();
            updateReqVO.setBalanceTime(now);
            internalCodeService.updateBalance(updateReqVO);
        } catch (MybatisPlusException mpe) {
            throw new ServiceException(ERROR_STATUS, mpe.getMessage());
        }
        return success(true);
    }

    @GetMapping("/getWorkstationFromInternalCode")
    @Operation(summary = "根据内码获取工位信息")
    public CommonResult<List<WorkstationRespVO>> getWorkstationFromInternalCode(@RequestParam("code") String code) {

        // 由于不知道属于哪种码,分别去查成品码,内码
        ProductionCodeDO productionCodeDO = productionCodeMapper.selectById(code);
        InternalCodeDO internalCodeDO = internalCodeMapper.selectById(code);

        if (null == productionCodeDO
                && null == internalCodeDO
        ) {
            throw new ServiceException(ERROR_STATUS, "扫码不存在,请重新扫码");
        }

        // 如果是成品码
        if (null != productionCodeDO) {
            String internalCode = productionCodeDO.getInternalCode();
            internalCodeDO = internalCodeService.getInternalCode(internalCode);
        }

        List<WorkstationRespVO> workstationRespVOList = internalCodeService.getWorkstationFromInternalCode(internalCodeDO.getId());

        return success(workstationRespVOList);
    }

    @GetMapping("/clearWeightHistory")
    @Operation(summary = "清除该内码的所有称重数据、平衡和刚性数据")
    public CommonResult<Boolean> clearWeightHistory(@RequestParam("code") String code, @RequestParam("workstationIdList") String workstationIdList) {
        if (StringUtils.isBlank(code)) {
            throw new ServiceException(ERROR_STATUS, "未扫码");
        }

        // 由于不知道属于哪种码,分别去查成品码,内码
        ProductionCodeDO productionCodeDO = productionCodeMapper.selectById(code);
        InternalCodeDO internalCodeDO = internalCodeMapper.selectById(code);
        // 如果以上都查不到,则返回提示信息
        if (null == productionCodeDO
                && null == internalCodeDO
        ) {
            throw new ServiceException(ERROR_STATUS, "扫码不存在,请重新扫码");
        }
        if (null == productionCodeDO && null != internalCodeDO) {
            productionCodeDO = productionCodeMapper.selectOne("internal_Code", code);
        }

        // 如果是成品码
        if (null != productionCodeDO) {
            String internalCode = productionCodeDO.getInternalCode();
            internalCodeDO = internalCodeService.getInternalCode(internalCode);

            HashMap<String, Object> params = new HashMap<>();
            params.put("internalCode", internalCode);
            params.put("workstationIdList", workstationIdList);

            internalCodeService.clearWeightHistory(params);
        }else {
            String internalCode = internalCodeDO.getId();

            HashMap<String, Object> params = new HashMap<>();
            params.put("internalCode", internalCode);
            params.put("workstationIdList", workstationIdList);

            internalCodeService.clearWeightHistory(params);
        }

        return success(true);
    }

    /**
     * 设置规格型号,产品长度,订单类型,订单详情id
     *
     * @param datas
     * @return
     */
    public List<InternalCodeRespVO> setFlex(List<InternalCodeRespVO> datas) {
        // 设置规格型号,产品长度,订单类型
        internalCodeService.updateFlex(datas);

        // 根据订单编号,产品规格,长度等设置订单详情id
        internalCodeService.setOrderDetailId(datas);

        return datas;
    }

    // /**
    //  * 根据订单编号,产品规格,长度等设置订单详情id
    //  * @param datas
    //  * @return
    //  */
    // public List<InternalCodeRespVO> setOrderDetailId(List<InternalCodeRespVO> datas) {
    //     if (CollectionUtil.isEmpty(datas)) {
    //         return datas;
    //     }
    //
    //     List<InternalCodeRespVO> collect = datas.stream()
    //             .filter(c -> StringUtils.isBlank(c.getOrderDetailId()))
    //             .collect(Collectors.toList());
    //
    //     if (CollectionUtil.isNotEmpty(collect)) {
    //         internalCodeService.updateOrderDetailId(collect);
    //     }
    //
    //     return datas;
    // }

    @PostMapping("/listWorkstationDetail")
    @Operation(summary = "获得生产订单详情分页")
    public CommonResult<PageResult<InternalCodeWorkstationRespVO>> listWorkstationDetail(@RequestBody InternalCodePageReqVO pageReqVO) {
        PageResult<InternalCodeWorkstationRespVO> pageResult = internalCodeService.listWorkstationDetail(pageReqVO);
        return success(pageResult);
    }

    @PostMapping("/listCurrentWorkstationDetail")
    @Operation(summary = "获得生产订单详情分页")
    public CommonResult<PageResult<InternalCodeWorkstationRespVO>> listCurrentWorkstationDetail(@RequestBody InternalCodePageReqVO pageReqVO) {
        pageReqVO.setLoginUserId(SecurityFrameworkUtils.getLoginUserId());
        PageResult<InternalCodeWorkstationRespVO> pageResult = internalCodeService.listCurrentWorkstationDetail(pageReqVO);
        return success(pageResult);
    }



    @GetMapping("/listCurrentUserWorkstationOrderInfo")
    @Operation(summary = "获取当前人员工位订单信息")
    public CommonResult<List<Map<String, Object>>> listCurrentUserWorkstationOrderInfo(@RequestParam("deptId")Integer deptId, @RequestParam("cacheOrderCode")String cacheOrderCode) {
        List<Map<String, Object>> list = internalCodeService.listCurrentUserWorkstationOrderInfo(deptId, cacheOrderCode, SecurityFrameworkUtils.getLoginUserId());
        return success(list);
    }

    @GetMapping("/exportWorkstationDetail")
    @Operation(summary = "获得生产订单详情分页")
    public void exportWorkstationDetail(@Valid InternalCodePageReqVO pageReqVO, HttpServletResponse response) throws IOException {
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        PageResult<InternalCodeWorkstationRespVO> pageResult = internalCodeService.listWorkstationDetail(pageReqVO);
        List<InternalCodeWorkstationRespVO> list = pageResult.getList();

        // 导出 Excel
        ExcelUtils.write(response, "产量总排程单三级报表.xls", "数据", InternalCodeWorkstationRespVO.class,list);

    }

    @GetMapping("/listCacheOrder")
    @Operation(summary = "获取缓存中的订单号")
    public CommonResult<Set> listCacheOrder() {
        Set set = internalCodeService.listCacheOrder();
        return success(set);
    }

}
